﻿using System;
using System.Linq;
using Kiwi.Container.Internal;

namespace Kiwi.Container.Activation
{
    public class BestFitConstructorComponentActivator
    {
        public static object ActivateComponent(Type type, IComponentResolver resolver)
        {
            var match = type
                .GetConstructors()
                .Select(c => new {constructor = c, parameters = c.GetParameters()})
                .OrderByDescending(c => c.parameters.Length)
                .Select(c => new
                                 {
                                     c.constructor,
                                     parameters =
                                 c.parameters.Select(p => resolver.TryResolve(p.ParameterType)).ToArray()
                                 })
                .Where(c => c.parameters.All(p => p != null))
                .FirstOrDefault();

            if (match == null)
            {
                Throw.ConstructorNotFound(type);
            }
            return match.constructor.Invoke(match.parameters);
        }
    }

    public class BestFitConstructorComponentActivator<T> : BestFitConstructorComponentActivator, IComponentActivator<T>
    {
        #region IComponentActivator<T> Members

        public object ActivateComponent(IComponentResolver resolver)
        {
            return ActivateComponent(typeof (T), resolver);
        }

        #endregion
    }
}